package org.base.oj.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.base.oj.common.BusinessException;
import org.base.oj.common.ParamsPage;
import org.base.oj.common.redis.RedisCache;
import org.base.oj.domain.Question;
import org.base.oj.domain.dto.QuestionDTO;
import org.base.oj.domain.enumEntity.QuestionEnum;
import org.base.oj.mapper.QuestionMapper;
import org.base.oj.service.QuestionOptionsService;
import org.base.oj.service.QuestionSampleService;
import org.base.oj.service.QuestionService;
import org.base.oj.service.QuestionTestCaseService;
import org.base.oj.service.question.QuestionManger;
import org.base.oj.utils.CommonUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.List;
import java.util.Map;
import java.util.Objects;

@Service
@Slf4j
public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> implements QuestionService {
    @Autowired
    private QuestionManger questionManger;
    @Autowired
    private QuestionOptionsService questionOptionsService;
    @Autowired
    private QuestionSampleService questionSampleService;
    @Autowired
    private QuestionTestCaseService questionTestCaseService;
    @Autowired
    private RedisCache redisCache;
    @Value("${GlobalValue.redisQuestionNumberKey}")
    private  String redisQuestionNumberKey;
    @Override
    @Transactional
    public void saveQuestionAndOptions(QuestionDTO questionDTO) throws BusinessException {
        Question question = questionDTO;
        Long questionNumber = getQuestionNumber();
        //设置题号
        question.setQuestionNumber("P" + ( questionNumber + 1));
        save(question);
        questionDTO.getOptions().forEach(questionOption ->
            questionOption.setQuestionPid(question.getId())
        );
        //编程题保存用例
        if (Objects.equals(questionDTO.getType(), QuestionEnum.PROGRAM.getType())){
            //设置样例
            questionDTO.getQuestionSamples().forEach(questionSample ->
                    questionSample.setQuestionId(question.getId())
            );
            //设置测试用例
            questionDTO.getQuestionTestCases().forEach(questionTestCase ->
                    questionTestCase.setQuestionId(question.getId())
            );
            questionSampleService.saveBatch(questionDTO.getQuestionSamples());
            questionTestCaseService.saveBatch(questionDTO.getQuestionTestCases());
        }


        questionOptionsService.saveBatch(questionDTO.getOptions());

        //更新题号
        reRedisQuestionNumber(questionNumber);

    }

    /**
     * 分页查询获取题目基本信息--不含选项
     * @param page
     * @return
     */
    @Override
    public Page<Question> getQuestionPage(ParamsPage page) {
        Page<Question> res = new Page<>(page.getCurrent(), page.getPageSize());
        if (page.getParams() == null || page.getParams().isEmpty()) return page(res);
        LambdaQueryWrapper<Question> queryWrapper = new LambdaQueryWrapper<>();
        Map<String, Object> params = page.getParams();
        params.forEach((key, value) -> {
            switch (key) {
                case "title":
                    queryWrapper.like(Question::getTitle, value);
                    break;
                case "type":
                    queryWrapper.eq(Question::getType, value);
                    break;
                case "difficulty":
                    queryWrapper.eq(Question::getDifficulty, value);
                    break;
                case "area":
                    queryWrapper.eq(Question::getArea, value);
                    break;
                case "year":
                    queryWrapper.eq(Question::getYear, value);
                    break;
                case "questionNumber":
                    queryWrapper.eq(Question::getQuestionNumber, value);
                    break;
            }
        });
        return page(res, queryWrapper);
    }


    /**
     * 获取题号
     * @return
     * @throws BusinessException
     */
    public Long getQuestionNumber() throws BusinessException {
        Long questionNumber = redisCache.getCacheObject("questionNumber");
        if (ObjectUtils.isEmpty(questionNumber)){
            //题号处理
            Page<Question> page = new Page<>(1, 1);
            LambdaQueryWrapper<Question> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.orderByDesc(Question::getCreateTime);
            List<Question> res = page(page, queryWrapper).getRecords();
            if (res != null && !res.isEmpty()){
                //获取最新题号
                questionNumber =  CommonUtils.getValueFromString(res.get(0).getQuestionNumber());
            }else{
               questionNumber = 10000L;
            }
            redisCache.setCacheObject(redisQuestionNumberKey,questionNumber);
        }
        return questionNumber;
    }

    /**
     * 保存完题目后新的题号
     * @param questionNumber 新题号
     * @throws BusinessException
     */
    public void reRedisQuestionNumber(Long questionNumber) throws BusinessException {
        redisCache.setCacheObject(redisQuestionNumberKey,questionNumber + 1 );
    }
    public void test(){
        System.out.println(questionManger);
    }
}
